Design Patterns - Observer Pattern
01 Sep 2017Intent
According to Gang of Four, the intent of Observer Pattern is to:
Defines a One to Many dependency between objects so that when one object changes State, all of its dependencies are notified and updated automatically.
Problem
You need to notify a varying list of objects that an event has occurred.
Solution
Observers delegate the responsibility for monitoring for an event to a central object Subject
Participants
-
Subject - Object that holds the state of Observer registered with it. It maintains list of it’s dependencies called Observers and notifies them automatically of any state change.
-
Observers - Object are responsible for registering with the Subject and for getting the information from the Subject when notified.
Implementation
Have objects (Observers) that want to know when an event happens attach themselves to another object (Subject) that is watching for the event to occur or that triggers the even itself.
When the event occurs, the Subject tells the Observers that it has occurred.
Example
CurrentConditionsDisplay.java
package com.art.headfirst.WeatherStationApp.example;
/**
* Concrete Observer
*
* * Responsible for Registering with Subject
* * Implements Observer Interface
*
*/
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private float pressure;
public CurrentConditionsDisplay(Subject weatherData) {
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("Current Weather Condition:");
System.out.println("Temperature: " + temperature);
System.out.println("Humidity: " + humidity);
System.out.println("Pressure: " + pressure);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
this.pressure = pressure;
display();
}
}
DisplayElement.java
package com.art.headfirst.WeatherStationApp.example;
public interface DisplayElement {
void display();
}
Observer.java
package com.art.headfirst.WeatherStationApp.example;
public interface Observer {
void update(float temp, float humidity, float pressure);
}
Subject.java
package com.art.headfirst.WeatherStationApp.example;
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
WeatherData.java
package com.art.headfirst.WeatherStationApp.example;
import java.util.ArrayList;
/**
* Concrete Subject
*
* * Object that maintains list of Observers
* * Notifies on Updates
*
*/
public class WeatherData implements Subject {
private float temperature;
private float humidity;
private float pressure;
private ArrayList observers;
public WeatherData() {
observers = new ArrayList();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int i = observers.indexOf(observer);
if (i >= 0) {
observers.remove(i);
} else {
throw new IllegalStateException("Unknown Observer");
}
}
@Override
public void notifyObservers() {
observers.forEach(o -> {
Observer observer = (Observer) o;
observer.update(temperature, humidity, pressure);
});
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public void measurementsChanged() {
notifyObservers();
}
}
WeatherStation.java
package com.art.headfirst.WeatherStationApp.example;
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(57.4f, 53, 29.95f);
}
}
Summary
Observer pattern defines one-to-many relationship between a set of objects. It provides an object design where subjects and observers are loosely coupled.
Tweet Follow @aayushtuladhar